local assets =
{
    Asset("ANIM", "anim/npc_fx_red_portal.zip"),

}
local function GetStringsTable()
    return TUNING.NPC_CHAT_TABLE[ type(TUNING.__NPC_LANGUAGE)=="function" and TUNING.__NPC_LANGUAGE() or TUNING.__NPC_LANGUAGE ] ["npc_item_red_portal"] or {}
end

local function Anim_Out(inst)
    if inst.anim_out ~= true then
        inst.anim_out = true
        inst.anim_in = false
        inst.AnimState:PlayAnimation("out_idle",true)    
    end
end
local function Anim_In(inst)
    if inst.anim_in ~= true then
        inst.anim_in = true
        inst.anim_out = false
        inst.AnimState:PlayAnimation("in_idle",true)
        inst.AnimState:HideSymbol("beam_bod")
    end
end

------------------------------------------------------------------------
local function Check_player_unlock_wortox()
    for k, player in pairs(AllPlayers) do
        if player and player.components.playercontroller and player.npc_base_lib then
            local unlock_list = player.npc_base_lib:___Get_DLC_Character_List()
            if unlock_list["wortox"] == true then
                return player
            end
        end
    end
    return false
end

local function Check_target_unlock_wortox(player)
    if player and player.components.playercontroller and player.npc_base_lib then
        local unlock_list = player.npc_base_lib:___Get_DLC_Character_List()
        if unlock_list["wortox"] == true then
            return true
        end
    end
    return false
end

local function HideDoor(inst)
    if inst:HasTag("ShowDoor") or not inst:HasTag("init_flag") then
        inst:AddTag("init_flag")
        inst:Hide()
        inst:RemoveTag("ShowDoor")
        inst:AddTag("HideDoor")
        inst.Light:Enable(false)
        local pt = Vector3(inst.Transform:GetWorldPosition())
        inst.Transform:SetPosition(pt.x,30,pt.z)
    end
end
local function ShowDoor(inst)
    Anim_Out(inst)
    if inst:HasTag("HideDoor")  or not inst:HasTag("init_flag") then
        inst:AddTag("init_flag")
        inst.Light:Enable(true)
        inst:Show()
        inst:AddTag("ShowDoor")
        inst:RemoveTag("HideDoor")
        local pt = Vector3(inst.Transform:GetWorldPosition())
        inst.Transform:SetPosition(pt.x,0,pt.z)
    end
end

local function Spawn_Soul(inst,_table)
    local pt = Vector3(_table.inst.Transform:GetWorldPosition())
    SpawnPrefab("npc_projectile_wortox_soul_spawn"):PushEvent("Set",{
        pt = pt,
        target = inst,
        OnHit_fn = function(inst,attacker,target)
            target:PushEvent("Get_Soul",1)
        end
    })
end

local function daily_task_init(inst)

    inst:WatchWorldState("cycles",function()    
        local task_finish_times = TheWorld.npc_everything_data:Add("npc_item_red_portal.Task_Finish_Times",0) 
        if math.random(100) < math.clamp(task_finish_times*20,0,80) then
            return
        end

        inst:DoTaskInTime(math.random(30,200),function()
            for k, temp_player in pairs(AllPlayers) do
                        if math.random(100) < 30 and temp_player and temp_player.components.playercontroller and Check_target_unlock_wortox(temp_player) and not temp_player:HasTag("playerghost") then
                                    local fx = SpawnPrefab("npc_projectile_wortox_soul_spawn")
                                    fx:PushEvent("Set",{
                                        pt = Vector3(temp_player.Transform:GetWorldPosition()),
                                        target = inst,
                                        OnHit_fn = function(inst,attacker,target)
                                            target:PushEvent("Get_Soul",0)
                                        end
                                    })
                                    fx:DoTaskInTime(5,fx.Remove)
                        end
            end
        end)
    end)
end
------------------------------------------------------------------------
local function Spawn_wortox(inst,player)
    Anim_In(inst)
    local pt = Vector3(inst.Transform:GetWorldPosition())
    local npc = SpawnPrefab("wortox_npc")
    npc.__link_player = player
    npc:Hide()
    npc:DoTaskInTime(0.1,function()
        npc:Show()
        SpawnPrefab("npc_fx_spawn"):PushEvent("Set",{pt = pt})
        npc.Transform:SetPosition(pt.x,0,pt.z)
        -- local tarplayer = npc:GetNearestPlayer()
        -- npc:PushEvent("player_link",tarplayer)
        npc:AddDebuff("npc_event_wortox_from_portal", "npc_event_wortox_from_portal")
    end)
    inst:AddTag("wortox_task")
end
-----------------------------------------------------------------
local function Spawn_krampus(inst)
    local pt = Vector3(inst.Transform:GetWorldPosition())
    local krampus = SpawnPrefab("krampus")
    krampus.Transform:SetPosition(pt.x,0,pt.z)
    SpawnPrefab("npc_fx_spawn"):PushEvent("Set",{pt = pt,scale = Vector3(2,2,2) })
end
-----------------------------------------------------------------
local function Get_Soul_Event(inst,num)
    local ret_num = inst.npc_everything_data:Add("soul num",1)
    local player = Check_player_unlock_wortox()
    local max_soul_num = 100
    if TUNING.NPC_MOD_TEST_DEBUG then
        max_soul_num = 10
    end
    if player and ret_num >= max_soul_num and inst.npc_everything_data:Get("wortox_spawned") ~= true then
        inst.npc_everything_data:Set("wortox_spawned",true)
        inst:DoTaskInTime(1.5,function()
            Spawn_wortox(inst, player)            
        end)
    end


    if inst.npc_everything_data:Get("wortox_spawned") ~= true and math.random(1000) <= 50 then
        Anim_In(inst)
        inst:DoTaskInTime(1.5,Spawn_krampus)
        inst:DoTaskInTime(5,Anim_Out)
    end

end
------------------------------------------------------------------------
local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
	inst.entity:AddNetwork()
	inst.entity:AddMiniMapEntity()
    inst.entity:AddLight()


    inst.entity:AddAnimState()
    inst.AnimState:SetBank("monkey_island_portal")
    inst.AnimState:SetBuild("monkey_island_portal")
    inst.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
    inst.AnimState:SetLightOverride(1)

    inst.AnimState:OverrideSymbol("fx_crack", "npc_fx_red_portal", "fx_crack")
    inst.AnimState:OverrideSymbol("fx_glow_out", "npc_fx_red_portal", "fx_glow_out")
    inst.AnimState:OverrideSymbol("portal_arm_ind_outline", "npc_fx_red_portal", "portal_arm_ind_outline")
    inst.AnimState:OverrideSymbol("portal_center_outline", "npc_fx_red_portal", "portal_center_outline")

    inst.AnimState:SetScale(0.5,0.5,0.5)
    -- inst.AnimState:PlayAnimation("out_idle",true)
    -- inst.AnimState:PlayAnimation("in_idle",true)
    -- inst.AnimState:HideSymbol("beam_bod")
    -- Anim_Out(inst)

	inst.MiniMapEntity:SetIcon("monkey_island_portal.png")
    inst.MiniMapEntity:SetPriority(1)

    inst.Light:SetIntensity(.7)
    inst.Light:SetRadius(3)
    inst.Light:SetFalloff(.8)
    inst.Light:SetColour(200/255, 18/255, 18/255)
    inst.Light:Enable(false)

    -- inst:AddTag("ignorewalkableplatforms")
    inst:AddTag("NOBLOCK")
    inst:AddTag("npc_item_red_portal")

    inst.entity:SetPristine()
    if not TheWorld.ismastersim then
        return inst
    end
    inst:AddComponent("npc_base_lib")
    inst:AddComponent("npc_everything_data")


    inst:AddComponent("inspectable") --可检查组件

    inst:AddComponent("named")
    -- inst.components.named:SetName(tostring(_table.Name))
    inst.components.named:SetName(GetStringsTable().name)
    STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_red_portal")] = GetStringsTable().inspect_str  --人物检查的描述

    -- inst:DoPeriodicTask(1,function()
    --     if inst:IsNearPlayer(5) then
    --         Anim_In(inst)
    --     else
    --         Anim_Out(inst)
    --     end
    -- end)
    ------------------------------------------------------------------------------------------------------
    inst:DoPeriodicTask(10,function()
        if inst:HasTag("wortox_task") then
            return
        end
        if Check_player_unlock_wortox() ~= false then
            ShowDoor(inst)
        else
            HideDoor(inst)
        end
    end)

    inst:ListenForEvent("Get_Soul",Get_Soul_Event)

    daily_task_init(inst)
    ------------------------------------------------------------------------------------------------------
    inst:ListenForEvent("Remove",function()
        inst.scale = 0.5
        inst.remove_task = inst:DoPeriodicTask(FRAMES, function()
            inst.AnimState:SetScale(inst.scale, inst.scale, inst.scale)
            inst.scale = inst.scale - 0.02
            if inst.scale <= 0  then
                if inst.remove_task then
                    inst.remove_task:Cancel()
                end
                inst:Remove()
                TheWorld.npc_everything_data:Add("npc_item_red_portal.Task_Finish_Times",1)
            end
        end)
    end)
    ------------------------------------------------------------------------------------------------------
    ---- 唯一的门
    if TheWorld.npc_item_red_portal ~= nil then
        TheWorld.npc_item_red_portal:Remove()
        TheWorld.npc_item_red_portal = nil
    end
    TheWorld.npc_item_red_portal = inst
    -----------------------------------------------
    local TheWorld_entity_death_event_fn = function(_,_table)
        -- print("TheWorld entity_death event",_table,_table.inst)
        if _table and _table.inst then
            local door = TheWorld.npc_item_red_portal
            local pt = Vector3(_table.inst.Transform:GetWorldPosition())
            if door and door:IsValid() and door:HasTag("ShowDoor") and  TheWorld.npc_base_lib:Dsitance_T2P(door,pt) < 50 then
                Spawn_Soul(door,_table)
            end
        end
    end

    if inst._onentitydeathfn == nil then
        inst._onentitydeathfn = function(src, data) TheWorld_entity_death_event_fn(inst, data) end
        inst:ListenForEvent("entity_death", inst._onentitydeathfn, TheWorld)
        inst:ListenForEvent("entity_death_npc_in_container", inst._onentitydeathfn, TheWorld)
    end

    ------------------------------------------------------------------------------------------------------
    -- -- --  inst 删除的时候移除 TheWorld 的 entity_death fn
    inst.Remove___npc_old = inst.Remove
    inst.Remove = function(inst)
        if TheWorld.npc_item_red_portal == inst then
            inst:RemoveEventCallback("entity_death", inst._onentitydeathfn, TheWorld)
            inst:RemoveEventCallback("entity_death_npc_in_container", inst._onentitydeathfn, TheWorld)
            TheWorld.npc_item_red_portal = nil
        end
        inst:Remove___npc_old()
    end

    ------------------------------------------------------------------------------------------------------
    return inst
end

return Prefab("npc_item_red_portal", fn,assets)